package com.cjm.one.security.config;

import cn.hutool.core.util.ReUtil;
import com.cjm.one.security.annotation.Within;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import cn.hutool.extra.spring.SpringUtil;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.springframework.core.annotation.AnnotationUtils;

import java.util.*;
import java.util.regex.Pattern;

@Slf4j
@Configuration
@ConfigurationProperties(prefix = "security.client")
@Data
public class PermissionPathPropertis implements InitializingBean {
    private static final Pattern FORMAT = Pattern.compile("\\{(.*?)\\}");

    private List<String> ignoreUrlList = new ArrayList<>();

    private final String[] ignoreUrl = new String[]{"/admin/auth/system/login",
            "/admin/auth/system/captchaCode",
            "/app/customer/emailCode",
            "/app/customer/login",
            "/app/pay/alipay/notify",
            "/app/customer/register",
            "/app/customer/checkEmail",
            "/app/goods/sku/**",
            "/app/goods/category/**",
            "/app/goods/info/**",
            "/app/custom/grade/**",
            "/favicon.ico",
            "/swagger-resources/**",
            "/webjars/**",
            "/v3/**",
            "/doc.html",
            "/swagger-ui.html"};


    @Override
    public void afterPropertiesSet() {
        ignoreUrlList.addAll(Arrays.asList(ignoreUrl) );
        RequestMappingHandlerMapping mapping = SpringUtil.getBean("requestMappingHandlerMapping");
        Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();
        for (RequestMappingInfo info : map.keySet()) {
            HandlerMethod handlerMethod = map.get(info);
            // 获取方法上边的注解 替代path variable 为 *
            Within method = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), Within.class);
            Optional.ofNullable(method)
                    .ifPresent(inner -> Objects.requireNonNull(info.getPathPatternsCondition())
                            .getPatternValues()
                            .forEach(url -> {
                                ignoreUrlList.add(ReUtil.replaceAll(url, FORMAT, "*"));
                                log.info("url----:{}", ReUtil.replaceAll(url, FORMAT,"*"));
                            }));
            // 获取类上边的注解, 替代path variable 为 *
            Within controller = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), Within.class);
            Optional.ofNullable(controller)
                    .ifPresent(inner -> Objects.requireNonNull(info.getPathPatternsCondition())
                            .getPatternValues()
                            .forEach(url -> ignoreUrlList.add(ReUtil.replaceAll(url, FORMAT,"*"))));
        }

    }
}
